﻿/*
 * Df
 * 2016.9.30
 */
using System;
using System.Collections.Generic;
using System.Drawing;
#region 数据库操作
using ADOX;  //32位                
using System.Data.OleDb;//32位
#endregion
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Threading;
using MouseKeyboardLibrary;//系统全局获取键盘输入  //只支持3.5以下的dotnetFx
using System.Xml;
using System.Runtime.InteropServices;
using System.Web;

//using System.Text.EncodingUTF7;
namespace df
{



    public partial class MainForm : share
    {


        public MainForm()
        {


            InitializeComponent();
            SetForegroundWindow(Handle);
            //SetWindowPos(Handle.ToInt32(), -1, 0, 0, 0, 0, 0x001 | 0x002 | 0x040);
            notifyIcon1.Visible = false;
            notifyIcon1.Icon = df.Properties.Resources.book_0;
            this.Icon = notifyIcon1.Icon;
            keyboardHook.KeyDown += new KeyEventHandler(keyboardHook_KeyDown);//KeyDown           
            keyboardHook.Start();
            jp.BackColor = Color.Black;
            jp.ForeColor = Color.Red;
            CancelButton = ex;
            //FormBorderStyle = FormBorderStyle.FixedSingle;//禁止改变尺寸
            this.ControlBox = false;   // 设置不出现关闭按钮 

            ShowInTaskbar = false;
            txt.HideSelection = false;
            txt.DetectUrls = true;
            groupBox1.Text = "";
            getVersionNum();
            //角标闪烁
            timer2.Interval = 500;
            //淡入、淡出
            timer3.Interval = 100;
            timer3.Start();
            textBox1.AcceptsReturn = false;
            Text = config.formName;
            fW = Width; fH = Height;
            //禁用tab跳转
            txt.AcceptsTab = true;
            Control.CheckForIllegalCrossThreadCalls = false; //允许跨线程调用控件

            //loading
            loading.BackColor = txt.BackColor;
            loading.Image = Properties.Resources.loading;
            loading.Location = new Point(txt.Width / 2 - loading.Width / 2, txt.Height / 2 - loading.Height / 2);
            showLoading(false);



        }
        void MainFormLoad(object sender, EventArgs e)//窗体载入时执行
        {

            //数据初始化
            Cdb();


            //载入替身模式
            if (readConfig(config.switchDb).ToInt32() == 1)
            {
                SetWinform右键菜单(tool_shadow, "切换回主体", Type.red);
                if (!File.Exists(config.backupMdb))
                {
                    File.Copy(config.mainMdb, config.backupMdb, true);
                }
                updateConfig(config.switchDb, "0");
                config.mainMdb = config.backupMdb;
                db_shadow = false;

            }


            #region 动态设置参数
            setConfig();
            #endregion

            //自动保存            
            timer1.Interval = config.autoSaveDelay * 1000;
            _switch_auto_save = readConfig(config.switchAutoSave) == "1" ? true : false;
            switch_auto_save_Click(null, null);

            rdb();
            setCurIndex();

            //登录验证
            config.cloudNm = readConfig(config.cloud_nm);
            config.cloudPw = readConfig(config.cloud_pw);
            var para = new Dictionary<string, object>();
            para.Add("nm", config.cloudNm);
            para.Add("pw", config.cloudPw);
            var rt = post(config.api_login, para);
            if (rt != null && rt["status"].ToInt32() > 0)
            {
                updateConfig(config.token, rt["result"]["token"].ToString());
                hasLogin(true);
            }
            else
            {
                hasLogin(false);
            }





        }

        #region 全局







        int fW, fH;
        bool jpbl = true;//最大化、最小化切换


        int index = 0;
        bool sqk = true;

        #endregion

        #region 数据库操作


        /// <summary>
        /// 更新数据
        /// </summary>
        void updateNote(Type type)
        {
            Thread t = new Thread(updateNote);
            t.Start(type);
        }


        void updateNote(notes n)
        {
            Thread t = new Thread(updateNotes);
            t.Start(n);
        }

        /// <summary>
        /// 多线程
        /// 实时保存标题、内容
        /// </summary>
        /// <param name="o"></param>
        void updateNote(object o)
        {

            Type type = (Type)o;
            //sleep(3);
            if (type == Type.update_title)
                wdb(nm.Text, null, type);
            else if (type == Type.update_text)
                wdb(null, txt.Text, type);
            else
                wdb(nm.Text, txt.Text, type);
        }

        void updateNotes(object o)
        {
            notes note = (notes)o;
            wdb(note);
            rdb();
        }
        KeyboardHook keyboardHook = new KeyboardHook();//KeyboardHook  











        /// <summary>
        /// 操作文档数据
        /// </summary>
        /// <param name="title"></param>
        /// <param name="msg"></param>
        /// <param name="listN">列表序号</param>
        /// <param name="type"></param>
        void wdb(string title = "标题", string msg = "内容", Type type = Type.update_text)
        {
            try
            {
                notes note = new notes(title, msg);
                switch (type)
                {
                    case Type.insert:
                        //新建
                        xj.Text = "新建中...";
                        xj.Enabled = false;


                        string sql = string.Format("insert into `{0}`([title],[text],[date]) values(@title,@text,'{1}')", config.tableNote, DateTime.Today.ToString("yyyy年MM月dd日"));

                        int rt = (int)query(sql, Type.exe, Type.mainDb, note);
                        if (rt > 0)
                        {
                            sql = string.Format("select Id from `{0}` order by Id desc", config.tableNote);
                            DataTable dt = (DataTable)query(sql, Type.select);
                            int nid = dt.Rows[0][0].ToInt32();
                            int index = dataGridView1.Rows.Count;
                            updateConfig(config.cur_Index, index.ToString());
                            updateConfig(config.cur_Id, nid.ToString());
                            xj.Text = "新建";
                            xj.Enabled = true;

                        }
                        else
                        {
                            showMsg("新建失败");
                        }

                        break;

                    case Type.update_title:
                        //更新 

                        Text = "保存中...";
                        int id = readConfig(config.cur_Id).ToInt32();
                        sql = string.Format("UPDATE `{0}` SET [title]=@title WHERE Id ={1}", config.tableNote, id);
                        rt = (int)query(sql, Type.exe, Type.mainDb, note);
                        if (rt > 0)
                        {
                            //cmd.ExecuteNonQuery()对象是对insert,update,delete语句返回受影响的行数                            
                            showMsg(string.Format("{1}→保存成功→{0}", DateTime.Now.ToString(), nm.Text));
                        }
                        else
                        {
                            showMsg("保存出错");
                        }

                        rdb();
                        setRowList();
                        break;
                    case Type.update_text:
                        //更新 

                        Text = "保存中...";
                        id = readConfig(config.cur_Id).ToInt32();
                        sql = string.Format("UPDATE `{0}` SET [text]=@text WHERE Id ={1}", config.tableNote, id);
                        rt = (int)query(sql, Type.exe, Type.mainDb, note);
                        if (rt > 0)
                        {//cmd.ExecuteNonQuery()对象是对insert,update,delete语句返回受影响的行数                           
                            showMsg(string.Format("{1}→保存成功→{0}", DateTime.Now.ToString(), nm.Text));
                        }
                        else
                        {

                            showMsg("保存出错");
                        }
                        break;


                    case Type.update_auto:
                        //更新 
                        Text = "保存中...";
                        id = readConfig(config.cur_Id).ToInt32();
                        msg = txt.Text;
                        sql = string.Format("UPDATE `{0}` SET [title]=@title,[text]=@text WHERE Id ={1}", config.tableNote, id);
                        rt = (int)query(sql, Type.exe, Type.mainDb, note);
                        if (rt > 0)
                        {//cmd.ExecuteNonQuery()对象是对insert,update,delete语句返回受影响的行数                           
                            showMsg(string.Format("{1}→自动保存成功→{0}", DateTime.Now.ToString(), nm.Text));
                        }
                        else
                        {

                            showMsg("保存出错");
                        }
                        break;
                    default:
                        break;
                }


            }
            catch (Exception err)
            {
                showMsg("出错:" + err.ToString());
            }

        }


        void wdb(notes note)
        {
            try
            {
                //更新 
                Text = "保存中...";
                int id = note.id;
                string sql = string.Format("UPDATE `{0}` SET [title]=@title,[text]=@text WHERE Id ={1}", config.tableNote, id);
                int rt = (int)query(sql, Type.exe, Type.mainDb, note);
                if (rt > 0)
                {//cmd.ExecuteNonQuery()对象是对insert,update,delete语句返回受影响的行数                           
                    showMsg(string.Format("{1}→自动保存成功→{0}", DateTime.Now.ToString(), nm.Text));
                }
                else
                {

                    showMsg("保存出错");
                }

            }
            catch (Exception err)
            {
                showMsg("出错:" + err.ToString());
            }

        }


        /*
         * 
         *  今天遇到奇怪的问题，datagridview绑定datatable出现大红叉并且没有了滚动条，于是乎到网上找原因，网络真是个好东西，果然还真找到了，由于datagirdview是由主线成创建的，如果在子线程中访问的话会出现上述问题，解决方法就是将datagridview绑定数据的代码重新指定主线程绑定，至于为什么不能在子线程中访问主线程创建的控件，这个额也不知道呢  
解决方案：
private delegate void InvokeHandler();
//子线程中
 this.Invoke(new InvokeHandler(delegate()
{
     dataGridView1.DataSource = null;
     dataGridView1.DataSource = dgv_dt;
}));
 
         * 
         * 
         */
        /// <summary>
        /// 读取数据
        /// 
        /// 刷新列表或者读取某个文章的详情
        /// </summary>
        /// <returns></returns>
        DataTable rdb(int id = 0)
        {
            df:
            DataTable dt;
            try
            {
                string sql = string.Format("select `Id`,`title` from `{0}`", config.tableNote);  //id、title是必要字段
                if (id != 0)
                {
                    //读取单个文章的详情
                    sql = string.Format("select `title`,`text`,`date` from `{0}` where Id={1}", config.tableNote, id);
                    dt = (DataTable)query(sql, Type.select);

                }
                else


                {
                    //抓取文章标题列表
                    dt = (DataTable)query(sql, Type.select);
                    if (dt.Rows.Count <= 0)
                        return dt;

                    //子线程中
                    this.Invoke(new InvokeHandler(delegate ()
                    {
                        dataGridView1.DataSource = null;
                        dataGridView1.DataSource = dt;
                    }));
                    //this.dataGridView1.DataSource = dt;
                    this.dataGridView1.ColumnHeadersVisible = false;
                    this.dataGridView1.RowHeadersVisible = false;
                    dataGridView1.ForeColor = Color.Black;
                    dataGridView1.DefaultCellStyle.SelectionBackColor = Color.FromArgb(64, 128, 128);
                    dataGridView1.ReadOnly = true;
                    dataGridView1.AllowUserToAddRows = false;//不显示出dataGridView1的最后一行空白栏   
                    this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
                    dataGridView1.Columns[0].Visible = false;
                    dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
                }


            }
            catch (Exception err)
            {
                @base.Debug_Write(err.ToString());
                goto df;
            }


            return dt;
        }



        /// <summary>
        /// 设置参数
        /// </summary>
        void setConfig()
        {

            config.textFont = readConfig(config.text_font);
            //string[] font = config.textFont.Split('|');
            //txt.Font = new Font(font[0], font[1].ToInt32(), FontStyle.Regular);
            txt.Font = new FontConverter().ConvertFromString(config.textFont) as Font;
            config.textBgcolor = readConfig(config.text_bgcolor);
            txt.BackColor = ColorTranslator.FromHtml(config.textBgcolor);
            config.formLocation = readConfig(config.form_location);
            string[] form_location = config.formLocation.Split('|');
            Location = new Point(form_location[0].ToInt32(), form_location[1].ToInt32());
            config.formSize = readConfig(config.form_size);
            string[] form_size = config.formSize.Split('|');
            Size = new Size(form_size[0].ToInt32(), form_size[1].ToInt32());
            config.autoSaveDelay = readConfig(config.auto_save_delay).ToInt32();
        }

        /// <summary>
        /// 设置当前显示的数据
        /// 
        /// 打开最近使用的文档
        /// </summary>
        void setCurIndex()
        {
            int id = readConfig(config.cur_Id).ToInt32();
            DataTable dt = rdb(id);
            if (dt.Rows.Count > 0 && id > 0)
            {
                nm.Text = dt.Rows[0]["title"].ToString();
                txt.Text = dt.Rows[0]["text"].ToString();
                showMsg(nm.Text + "→" + dt.Rows[0]["date"].ToString());
                txt.Select(txt.Text.Length, 0);

                setRowList();
            }
        }

        /// <summary>
        /// 设置list选中状态
        /// </summary>
        void setRowList()
        {
            int index = readConfig(config.cur_Index).ToInt32();
            this.dataGridView1.Rows[index].Selected = true;
            this.dataGridView1.CurrentCell = this.dataGridView1.Rows[index].Cells[1];
            //this.dataGridView1.Rows[index].DefaultCellStyle.ForeColor = Color.FromArgb(200, Color.Red);


        }
        #endregion

        #region 控件

        /// <summary>
        /// 控制自动执行的脚本
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            updateNote(Type.update_auto);


        }

        private void 书签开ToolStripMenuItem_Click(object sender, EventArgs e)
        {

            if (sqk)
            {
                //分割线也占用一个位置
                SetWinform右键菜单(书签开ToolStripMenuItem, "书签关", Type.red);
                left_part.BringToFront();
                left_part.Visible = true;
                sqk = false;
            }
            else
            {
                SetWinform右键菜单(书签开ToolStripMenuItem, "书签开");
                left_part.Visible = false;
                sqk = true;

            }
        }
        public void 禁用多行文本框自动换行(KeyPressEventArgs textBox1_KeyPress_KeyPressEventArgs_e)
        {
            if (textBox1_KeyPress_KeyPressEventArgs_e.KeyChar == (char)System.Windows.Forms.Keys.Return) textBox1_KeyPress_KeyPressEventArgs_e.Handled = true;
        }

        /// <summary>
        /// 禁用搜索框回车换行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            禁用多行文本框自动换行(e);
        }
        bool db_shadow = true;
        /// <summary>
        /// 改变某一个右键菜单的样式
        /// </summary>
        /// <param name="某一个选项"></param>
        /// <param name="显示内容"></param>
        /// <param name="type"></param>
        void SetWinform右键菜单(ToolStripMenuItem 某一个选项, string 显示内容, Type type = Type.black)
        {

            某一个选项.Text = 显示内容;
            if (type == Type.black)
            {

                某一个选项.ForeColor = Color.Black;
            }
            else
            {
                某一个选项.ForeColor = Color.Red;
            }
        }

        /// <summary>
        /// 切换为替身
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dfToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (db_shadow)
                updateConfig(config.switchDb, "1");//切换为本体
            else
                updateConfig(config.switchDb, "0");//切换为替身
            Application.Restart();//重启当前app
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ex_Click(null, null);
        }

        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void scClick(object sender, EventArgs e)
        {
            Thread mythread = new Thread(uploadMdb);
            mythread.Start();
        }
        private delegate void InvokeHandler();
        void dataGridView1_CellClick(object o)
        {



            try
            {


                DataGridViewCellEventArgs e = (DataGridViewCellEventArgs)o;
                showMsg("加载中...");

                //当点击表头时，e.RowIndex=-1 
                if (e.RowIndex > -1)
                {
                    int id = this.dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToInt32();
                    if (id == 0)
                    {
                        showMsg("请选择一个");
                        return;
                    }
                    updateNote(new notes(nm.Text, txt.Text, readConfig(config.cur_Id).ToInt32()));

                    updateConfig(config.cur_Index, e.RowIndex.ToString());
                    updateConfig(config.cur_Id, id.ToString());
                    setCurIndex();

                }
                index = 0;

            }
            catch (Exception err)
            {
                @base.Debug_Write(err.ToString());
            }
        }

        /// <summary>
        /// 防止短时间内点击次数太多导致程序崩溃
        /// </summary>
        void clickDelay()
        {
            @base.sleep(0.6);
            delay_status = false;
            showLoading(false); dataGridView1.Enabled = true;
        }

        bool delay_status = false;
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                showLoading(true);
                dataGridView1.Enabled = false;
                if (delay_status)
                    return;
                dataGridView1.ReadOnly = true;
                delay_status = true;
                Thread delay = new Thread(clickDelay);
                delay.Start();

                Thread t = new Thread(dataGridView1_CellClick);
                t.Start(e);
            }
            catch
            {

            }
        }

        Type start_end = Type.start;

        /// <summary>
        /// 开场动画效果
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer3_Tick(object sender, EventArgs e)
        {
            if (start_end == Type.start)
            {

                this.Opacity += 0.05;
                if (this.Opacity > 0.99)
                {
                    left_part.Visible = false;
                    timer3.Stop();
                    nm.Visible = false;

                }
            }
            else
            {
                this.Opacity -= 0.05;
                if (this.Opacity < 0.09)
                {
                    left_part.Visible = false;
                    timer3.Stop();
                    Exit();
                }
            }
        }

        private void df论坛ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://forum.dfer.top/forum.php?gid=48");
        }



        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ss_Click(object sender, EventArgs e)
        {
            search();
        }
        /// <summary>
        /// 退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ex_Click(object sender, EventArgs e)
        {
            start_end = Type.end;
            updateNote(Type.update_auto);
            timer3.Start();
        }

        void TxtKeyDown(object sender, KeyEventArgs e)
        {
            //ctrl+A：全选
            if (e.KeyCode == System.Windows.Forms.Keys.A && e.Control)
            {
                txt.SelectAll();
            }
            //f11：插入时间
            if (e.KeyCode == System.Windows.Forms.Keys.F11)
            {
                int dz = txt.SelectionStart;
                txt.Text = txt.Text.Insert(dz, DateTime.Now.ToLongDateString());
                txt.SelectionStart = dz + DateTime.Now.ToLongDateString().Length;
                txt.ScrollToCaret();
            }
            //ctrl+s:保存
            if (e.KeyCode == System.Windows.Forms.Keys.S && e.Control)
            {
                updateNote(Type.update_title);
                updateNote(Type.update_text);
            }
        }

        private void nm_KeyDown(object sender, KeyEventArgs e)
        {
            //ctrl+s:保存
            if (e.KeyCode == System.Windows.Forms.Keys.S && e.Control)
            {
                updateNote(Type.update_title);
                updateNote(Type.update_text);
            }

        }

        bool ssxs = true;
        void MainFormKeyDown(object sender, KeyEventArgs e)
        {
            //开关侧栏
            if (e.KeyCode == System.Windows.Forms.Keys.F5)
            {
                left_part.BringToFront();
                left_part.Visible = true;
            }
            //不允许强制关闭窗口
            else if (e.KeyCode == System.Windows.Forms.Keys.F4 && e.Modifiers == System.Windows.Forms.Keys.Alt)
            {
                KeyPreview = true;
                e.Handled = true;
                showMsg("不允许使用该快捷键");

            }
            //搜索
            else if (e.KeyCode == System.Windows.Forms.Keys.F6)
            {
                if (ssxs)
                {

                    ss.BringToFront();

                    ss.Visible = true;
                    ss.BackColor = Color.FromArgb(5, 204, 212, 230);
                    ssm.BackColor = Color.FromArgb(5, 204, 212, 230);
                    ssxs = false;
                    textBox1.Focus();
                }
                else
                {

                    ss.Visible = false;
                    ssxs = true;
                }
            }

        }

        /// <summary>
        /// 新建
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void XjClick(object sender, EventArgs e)
        {


            //新建标签时保存之前的数据有可能导致数据混淆，故而禁用
            wdb(new notes(nm.Text, txt.Text, readConfig(config.cur_Id).ToInt32()));



            string title = "标题" + DateTime.Now;
            string msg = "内容";
            wdb(title, msg, Type.insert);

            //刷新列表
            rdb();


            setCurIndex();

        }
        void MainFormKeyUp(object sender, KeyEventArgs e)
        {

            //窗体提取
            if (e.KeyCode == System.Windows.Forms.Keys.F5)
            {
                left_part.Visible = false;
            }

            //保存
            else if (e.KeyCode == System.Windows.Forms.Keys.F4)
            {
                updateNote(Type.update_title);
                updateNote(Type.update_text);
            }
            //最小化
            else if (e.KeyCode == System.Windows.Forms.Keys.F3)
            {
                zxhClick(null, null);
            }



        }

        /// <summary>
        /// 最小化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void zxhClick(object sender, EventArgs e)
        {

            Visible = false;
            ShowInTaskbar = false;
            WindowState = FormWindowState.Minimized;
            notifyIcon1.Visible = true; //托盘图标可见
            jpbl = false;
            _switch_auto_save = false;
            switch_auto_save_Click(null, null);
            timer2.Start();
        }
        /// <summary>
        /// 打开文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void wjjClick(object sender, EventArgs e)
        {
            try
            {
                //Process.Start("explorer.exe", ".");
                Process.Start(".");
            }
            catch (Exception err)
            {
                @base.Debug_Write(err.ToString());
            }
        }


        /// <summary>
        /// 恢复窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void NotifyIcon1Click(object sender, EventArgs e)
        {

            if (x)
                WindowState = FormWindowState.Normal; //还原窗体
            else
                WindowState = FormWindowState.Maximized;
            notifyIcon1.Visible = false; //托盘图标隐藏
            left_part.Visible = false;
            Visible = true;
            jpbl = true;


            _switch_auto_save = true;
            switch_auto_save_Click(null, null);
        }

        /// <summary>
        /// 复制文件、文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void fzClick(object sender, EventArgs e)
        {
            try
            {//debug文件夹
                string FileName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
                FileName = FileName.Substring(FileName.LastIndexOf("\\"), FileName.Length - FileName.LastIndexOf("\\"));

                string root = System.AppDomain.CurrentDomain.BaseDirectory;
                string dir = root + @"Df书柜\";
                if (Directory.Exists(dir))
                {
                    @base.ClearFileAndDire(dir);
                }
                Directory.CreateDirectory(dir);
                File.Copy("Newtonsoft.Json.dll", dir + "Newtonsoft.Json.dll", true);
                File.Copy("MouseKeyboardLibrary.dll", dir + "MouseKeyboardLibrary.dll", true);
                File.Copy("Interop.ADOX.dll", dir + "Interop.ADOX.dll", true);
                File.Copy("Interop.ADODB.dll", dir + "Interop.ADODB.dll", true);
                File.Copy(root + FileName, dir + FileName, true);


                Clipboard.Clear();
                System.Collections.Specialized.StringCollection s = new System.Collections.Specialized.StringCollection();

                //必须是绝对地址
                s.Add(dir);

                Clipboard.SetFileDropList(s);   //编辑器里调试时会报错，但不影响使用
                MessageBox.Show("“" + dir + "”复制成功");
            }
            catch (Exception ex)
            {
                @base.Debug_Write(ex.ToString());
            }

        }


        /// <summary>
        /// 搜索框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="textBox1_KeyDown_KeyEventArgs_e"></param>
        private void ss_KeyDown(object sender, KeyEventArgs textBox1_KeyDown_KeyEventArgs_e)
        {
            textBox1.textBox里按ctrl则全选(textBox1_KeyDown_KeyEventArgs_e);

            if (textBox1_KeyDown_KeyEventArgs_e.KeyCode == System.Windows.Forms.Keys.Enter)
            {
                search();
            }

        }

        bool jpkg = true;
        /// <summary>
        /// 开关全局快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void jp_Click(object sender, EventArgs e)
        {
            if (jpkg)
            {
                keyboardHook.Stop(); jpkg = false;
                jp.BackColor = Color.Transparent;
                jp.ForeColor = SystemColors.ControlText;
            }
            else
            {
                keyboardHook.Start(); jpkg = true;
                jp.BackColor = Color.Black;
                jp.ForeColor = Color.Red;
            }



        }
        bool zy = true; int width;
        private void 左右ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (zy)
            {
                width = Width;
                Width = Screen.PrimaryScreen.WorkingArea.Width;
                Location = new Point(0, Location.Y);
                zy = false;
            }
            else
            {
                Width = width;

                zy = true;

            }

        }
        bool sx = true; int height;
        private void 上下ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (sx)
            {
                height = Height;
                Height = Screen.PrimaryScreen.WorkingArea.Height;
                Location = new Point(Location.X, 0);
                sx = false;
            }
            else
            {
                Height = height;

                sx = true;

            }
        }

        private void 快捷键ToolStripMenuItem_Click(object sender, EventArgs e)
        {

            string[] para = config.help;

            messagebox h = new messagebox(para);
            if (h.ShowDialog() == DialogResult.OK)
            {
                h.Dispose();

            }

        }


        private void 帮助ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string[] para = config.about;

            messagebox h = new messagebox(para);
            if (h.ShowDialog() == DialogResult.OK)
            {
                h.Dispose();

            }


        }


        #endregion

        #region 界面效果

        /// <summary>
        /// 设置控件移动边界
        /// 
        /// 限制其移动范围
        /// 
        /// 防止控件超出可见范围
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_LocationChanged(object sender, EventArgs e)
        {
            //屏幕尺寸
            int sW = Screen.PrimaryScreen.Bounds.Width;
            int sH = Screen.PrimaryScreen.Bounds.Height;
            //WinForm尺寸
            int wW = Width;
            int wH = Height;
            //winform在屏幕的坐标，以左上角的point为准
            int wX = Location.X;
            int wY = Location.Y;

            if (wX < -wW)
                this.Location = new Point(0, wY);
            if (wX > sW)
                this.Location = new Point(sW - wW, wY);
            if (wY < -wH)
                this.Location = new Point(wX, 0);
            if (wY > sH)
                this.Location = new Point(wX, sH - wH);

            config.formX = this.Location.X;
            config.formY = this.Location.Y;
            loading.Location = new Point(txt.Width / 2 - loading.Width / 2, txt.Height / 2 - loading.Height / 2);

        }

        private void 靠右ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            height = Height;
            Height = Screen.PrimaryScreen.WorkingArea.Height;
            Location = new Point(Screen.PrimaryScreen.Bounds.Width - Width, 0);
            sx = false;
        }

        private void 靠左ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            height = Height;
            Height = Screen.PrimaryScreen.WorkingArea.Height;
            Location = new Point(0, 0);
            sx = false;
        }

        private void 初始大小ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Width = fW;
            Height = fH;
        }


        int blink_num = 0;
        /// <summary>
        /// 让任务栏图标闪烁
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer2_Tick(object sender, EventArgs e)
        {
            if (!blink)
            {
                notifyIcon1.Icon = striped;
            }
            else
            {
                this.notifyIcon1.Icon = blank;
            }
            blink = !blink;
            blink_num++;

            if (blink_num > 10)
                timer2.Stop();

        }


        #endregion

        #region 函数

        private Icon blank = df.Properties.Resources.book_0;
        private Icon striped = df.Properties.Resources.book_1;
        private bool blink = false;


        bool x = true;

        /// <summary>
        /// 最大化、最小化切换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void mixOrMax()
        {
            if (x)
            {
                WindowState = FormWindowState.Maximized;
                x = false;
                txt.ScrollToCaret();
            }
            else
            {
                WindowState = FormWindowState.Normal;
                x = true;
                txt.ScrollToCaret();
            }
        }

        /// <summary>
        /// 全局快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void keyboardHook_KeyDown(object sender, KeyEventArgs e)
        {
            Console.WriteLine(e.KeyCode);

            //最大化、最小化
            if (e.KeyCode == System.Windows.Forms.Keys.F7)
            {
                if (jpbl)
                {
                    zxhClick(null, null);
                }
                else
                {
                    NotifyIcon1Click(null, null);
                }
            }
        }



        /// <summary>
        /// 退出
        /// </summary>
        void Exit()
        {
            if (!config.mailSuccess)
            {
                if (MessageBox.Show("邮件为发送完成，是否强制关闭") == DialogResult.OK)
                    //关闭的只是窗体，但rar和mail是多线程操作的，在一切结束后才会真正关闭！
                    //直接终结进程
                    @base.kill();

            }



            Dispose();




        }


        bool _switch_auto_save;





        /// <summary>
        /// 开、关自动保存
        /// 
        /// 特殊操作容易导致数据混淆，故而禁用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void switch_auto_save_Click(object sender, EventArgs e)
        {

            //if (_switch_auto_save)
            //{
            //    //开启自动保存       
            //    updateConfig(config.switchAutoSave, 1);
            //    SetWinform右键菜单(switch_auto_save, "关闭自动保存");
            //    timer1.Start();
            //    _switch_auto_save = false;
            //    showMsg("自动保存已开启");
            //}
            //else
            //{   //关闭自动保存
            //    updateConfig(config.switchAutoSave, 0);
            //    SetWinform右键菜单(switch_auto_save, "打开自动保存", Type.red);
            //    timer1.Stop();
            //    _switch_auto_save = true;
            //    showMsg("自动保存已关闭");
            //}

        }

        /// <summary>
        /// 全屏切换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {

            bool _fullscreen = this.WindowState == FormWindowState.Maximized ? false : true;

            if (_fullscreen)
            {
                this.WindowState = FormWindowState.Maximized;
                _fullscreen = false;
                SetWinform右键菜单(fullscreen_toolStripMenuItem1, "还原", Type.red);

            }
            else
            {
                this.WindowState = FormWindowState.Normal;
                _fullscreen = true;
                SetWinform右键菜单(fullscreen_toolStripMenuItem1, "全屏");
            }


        }

        private void cloud_login_Click(object sender, EventArgs e)
        {
            if (cloud_login.Text == "注销")
            {

                if (updateConfig(config.cloud_nm, "") > 0 && updateConfig(config.cloud_pw, "") > 0)
                {
                    hasLogin(false);
                    Text = "已注销";
                }

            }
            else
            {

                login l = new login();

                if (l.ShowDialog() == DialogResult.OK)
                {
                    Text = l.err.Text;
                    hasLogin(true);
                    l.Dispose();
                }

            }
        }

        /// <summary>
        /// 更换登录状态
        /// </summary>
        /// <param name="status">
        /// true:已登录
        /// false:已注销
        /// </param>
        void hasLogin(bool status)
        {

            if (status)
            {
                cloud_status.Visible = true;
                toolStripSeparator5.Visible = true;
                cloud_status.Text = "用户：" + config.cloudNm;
                cloud_status.Enabled = false;//让tb无法被选中
                cloud_upload.Visible = true;
                cloud_download.Visible = true;
                cloud_login.Text = "注销";
                修改密码ToolStripMenuItem.Visible = true;
            }
            else
            {
                toolStripSeparator5.Visible = false;
                cloud_status.Visible = false;
                cloud_status.Text = "未登录";
                cloud_upload.Visible = false;
                cloud_download.Visible = false;
                cloud_login.Text = "登录";
                修改密码ToolStripMenuItem.Visible = false;
            }



        }



        /// <summary>
        /// 上传mdb到邮箱
        /// </summary>
        public void uploadMdb()
        {

            try
            {
                df:
                config.mailSuccess = false;
                sc.Enabled = false;
                if (@base.IsFileInUse(config.mainMdb))
                {
                    goto df;
                }
                else
                {
                    showMsg("备份数据中...");

                    string desFile = string.Format(@".\backup\{0}_{1}", config.mainMdb, DateTime.Now.时间_yyyyMMddhhmmss());

                    //File.Create(@".\backup");
                    File.Copy(config.mainMdb, desFile, true);
                    showMsg("备份成功");
                    System.Net.Mail.MailMessage myMail = new System.Net.Mail.MailMessage();

                    string ac = readConfig(config.mail_ac);
                    string pw = readConfig(config.mail_pw);

                    if (pw == "")
                    {
                        showMsg("请在config文件设置密码");

                    }
                    else
                    {
                        //发送端到接收端的邮箱地址  
                        myMail = new System.Net.Mail.MailMessage(ac, "dbl315@qq.com");
                        //设置标题和内容
                        myMail.Subject = "备份mdb文件" + DateTime.Today.Month + "." + DateTime.Now.Day;
                        myMail.Body = DateTime.Now.ToString();

                        //建立邮件附件类的一个对象，语法格式为System.Net.Mail.Attachment(文件名，文件格式)  
                        System.Net.Mail.Attachment myAttachment = new System.Net.Mail.Attachment(desFile, System.Net.Mime.MediaTypeNames.Application.Octet);
                        myMail.Attachments.Add(myAttachment);


                        //建立发送对象client,验证邮件服务器，服务器端口，用户名，以及密码  
                        System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("smtp.qq.com", Convert.ToInt32("25"));
                        //id,pass

                        client.Credentials = new System.Net.NetworkCredential(ac, pw);

                        showMsg("上传中...");
                        client.Send(myMail);
                        showMsg("上传成功");

                        config.mailSuccess = true;
                    }
                }
            }
            catch (Exception ex)
            {
                @base.Debug_Write(ex.ToString());
            }
            sc.Enabled = true;
        }

        int search_num = 0;
        /// <summary>
        /// 搜索
        /// </summary>
        public void search()
        {
            txt.Focus();
            index = txt.Text.IndexOf(textBox1.Text, index);
            if (index < 0)
            {
                search_num = 0;
                index = 0;
                Text = "没找到";
                textBox1.Focus();
                return;
            }
            search_num++;
            Text = string.Format("搜索到第{0}个", search_num);
            txt.Select(index, textBox1.Text.Length);
            index = index + textBox1.Text.Length;
            //txt.SelectionStart = index;
            txt.ScrollToCaret();

            textBox1.Focus();

        }

        void showMsg(string msg)
        {


            groupBox1.Text = nm.Text;
            Text = msg;
            if (!db_shadow)
            {
                groupBox1.Text = "替身模式→" + groupBox1.Text;
                Text = "替身模式→" + Text;
            }


        }



        private void 修改密码ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            change_pw c = new change_pw();

            if (c.ShowDialog() == DialogResult.OK)
            {
                Text = c.err.Text;

                if (updateConfig(config.cloud_nm, "") > 0 && updateConfig(config.cloud_pw, "") > 0)
                {
                    hasLogin(false);

                }
                c.Dispose();
                cloud_login_Click(null, null);
            }
        }





        void showLoading(bool status)
        {

            if (status)
            {
                loading.Visible = true;
            }
            else
            {
                loading.Visible = false;
            }
        }
        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cloud_upload_Click(object sender, EventArgs e)
        {
            Text = "数据上传中...";

            showLoading(true);

            //读取单个文章的详情
            string sql = string.Format("select `title`,`text`,`date` from `{0}`", config.tableNote);
            DataTable dt = (DataTable)query(sql, Type.select);
            DataTable newDt = new DataTable();
            foreach (DataColumn item in dt.Columns)
            {
                newDt.Columns.Add(item.ColumnName, item.DataType);

            }


            foreach (DataRow item in dt.Rows)
            {

                //a["title"] = HttpUtility.HtmlEncode(item[0].ToString());
                item["text"] = item[1].ToString().String2Unicode();
                //a["time"] = item[2];
                newDt.Rows.Add(new object[] {
                    item[0],item[1],item[2]
                });
            }

            //读取书签
            int book_id = readConfig(config.cur_Id).ToInt32();
            int book_index = readConfig(config.cur_Index).ToInt32();

            //配置参数
            string book_config = string.Format("{0}?{1}?{2}?{3}?{4}", config.autoSaveDelay, config.formLocation, config.formSize, config.textBgcolor, config.textFont);


            var para = new Dictionary<string, object>();




            para.Add("data", newDt.ToJson());//防止特殊字符的传递出错
            para.Add("book_id", book_id);
            para.Add("book_index", book_index);
            para.Add("book_config", book_config);
            var rt = post(config.api_upload, para);

            if (rt != null)
            {
                Text = rt["msg"].ToString();

                if (rt["status"].ToInt32() > 0)
                    showLoading(false);
            }



        }
        /// <summary>
        /// 下载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cloud_download_Click(object sender, EventArgs e)
        {
            Text = "数据下载中...";
            showLoading(true);
            //下载会覆盖所有本地的内容，所以制作一个替身，让用户有一次反悔的机会
            File.Copy(config.mainMdb, config.backupMdb, true);

            var para = new Dictionary<string, object>();


            var rt = post(config.api_download, para);

            if (rt != null)
            {

                if (rt["status"].ToInt32() > 0)
                {
                    var data = rt["result"]["data"];
                    var book_id = rt["result"]["book_id"];
                    var book_index = rt["result"]["book_index"];
                    var book_config = rt["result"]["book_config"];

                    DataTable dt = data.ToDataTable();
                    if (dt.Rows.Count <= 0)
                    {
                        showMsg("线上没有数据");
                        showLoading(false);
                        return;

                    }

                    //更新文档
                    //重建表，从而使其重新自增
                    string sql = string.Format("DROP TABLE `{0}`", config.tableNote);
                    int r = (int)query(sql, Type.exe);
                    createNote();
                    foreach (DataRow item in dt.Rows)
                    {
                        notes pa = new notes(item["title"].ToString(), item["text"].ToString().Unicode2String());
                        sql = string.Format("insert into `{0}`([title],[text],[date]) values(@title,@text,'{1}')", config.tableNote, item["date"]);
                        r = (int)query(sql, Type.exe, Type.mainDb, pa);
                    }
                    //更新文档id、书签
                    r = updateConfig(config.cur_Id, book_id);
                    r = updateConfig(config.cur_Index, book_index);
                    //更新参数
                    string[] configs = book_config.ToString().Split('?');
                    if (configs.Length == 5)
                    {
                        if (updateConfig(config.auto_save_delay, configs[0]) > 0 && updateConfig(config.form_location, configs[1]) > 0 && updateConfig(config.form_size, configs[2]) > 0 && updateConfig(config.text_bgcolor, configs[3]) > 0 && updateConfig(config.text_font, configs[4]) > 0)
                        {
                            r = 100;
                        }
                    }
                    //更新成功就重载窗体
                    if (r > 0)
                    {
                        setConfig();
                        rdb();
                        setCurIndex();
                        showLoading(false);
                    }
                    else
                        Text = "数据安装出错";
                }

                Text = rt["msg"].ToString();

            }

        }

        private void tool_Click(object sender, EventArgs e)
        {
            Point p = PointToScreen(new Point(0, 0));
            p.X += Width;
            contextMenuStrip1.Show(p);
        }

        private void option_Click(object sender, EventArgs e)
        {
            option o = new option();
            if (o.ShowDialog() == DialogResult.OK)
            {
                //timer1.Stop();
                //timer1.Interval = config.autoSaveDelay * 1000;
                //timer1.Start();
                string[] formLocation = config.formLocation.Split('|');
                Location = new Point(formLocation[0].ToInt32(), formLocation[1].ToInt32());
                string[] form_size = config.formSize.Split('|');
                Size = new Size(form_size[0].ToInt32(), form_size[1].ToInt32());
                txt.BackColor = System.Drawing.ColorTranslator.FromHtml(config.textBgcolor);

                nm.Font = txt.Font = new FontConverter().ConvertFromString(config.textFont) as Font;

                showMsg("参数设置完成");

                o.Dispose();
            }
        }

        private void nm_MouseLeave(object sender, EventArgs e)
        {
            nm.Visible = false;
        }

        private void txt_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Y <= 3)
                nm.Visible = true;

        }

        private void nm_TextChanged(object sender, EventArgs e)
        {

        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
            config.formW = Width;
            config.formH = Height;
        }






        /// <summary>
        /// 获取当前版本号
        /// </summary>
        void getVersionNum()
        {
            FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
            //对应程序集信息里的文件版本
            verNum.Text = string.Format("version {0}", myFileVersionInfo.ProductVersion);
            verNum.Enabled = false;
            config.verNum = verNum.Text;
        }

        /// <summary>
        /// 让窗体始终置顶
        /// </summary>
        /// <param name="hWnd">窗体句柄</param>
        /// <returns></returns>
        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);//设置此窗体为活动窗体



        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        public static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
        #endregion








    }

}

